using B.S.XZYData.Api.Wrter.Application.Command.Approval;
using B.S.XZYData.Domain.ZSH;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.XZYData.Api.Wrter.Application.Handler.Approval
{
    /// <summary>
    /// 重新提交申请处理器
    /// </summary>
    public class ResubmitApplicationHandler : IRequestHandler<ResubmitApplicationCommand, ApiResult<bool>>
    {
        private readonly IBaseRepository<WorkflowInstanceModel> _workflowInstanceRepo;
        private readonly IBaseRepository<AuditModel> _auditRepo;
        private readonly ILogger<ResubmitApplicationHandler> _logger;

        public ResubmitApplicationHandler(
            IBaseRepository<WorkflowInstanceModel> workflowInstanceRepo,
            IBaseRepository<AuditModel> auditRepo,
            ILogger<ResubmitApplicationHandler> logger)
        {
            _workflowInstanceRepo = workflowInstanceRepo;
            _auditRepo = auditRepo;
            _logger = logger;
        }

        public async Task<ApiResult<bool>> Handle(ResubmitApplicationCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<bool>();

            try
            {
                // 开始事务
                await _workflowInstanceRepo.BeginTranAsync();

                try
                {
                    // 1. 查询流程实例
                    var workflowInstance = await _workflowInstanceRepo.GetValue(request.WorkflowInstanceId);
                    if (workflowInstance == null)
                    {
                        res.Code = ApiEnum.Fail;
                        res.Msg = "流程实例不存在";
                        return res;
                    }

                    // 2. 验证申请人权限
                    if (workflowInstance.ApplicantUserName != request.ApplicantUserName)
                    {
                        res.Code = ApiEnum.Fail;
                        res.Msg = "只有申请人才能重新提交申请";
                        return res;
                    }

                    // 3. 验证当前状态是否允许重新提交（只有驳回状态才能重新提交）
                    if (workflowInstance.Status != "驳回")
                    {
                        res.Code = ApiEnum.Fail;
                        res.Msg = "只有驳回状态的申请才能重新提交";
                        return res;
                    }

                    // 4. 更新流程实例状态
                    workflowInstance.Status = "发起";
                    workflowInstance.StepName = "待审批";
                    workflowInstance.AuditUserName = null; // 重置审批人
                    workflowInstance.CompletedTime = null; // 重置完成时间
                    workflowInstance.ModifyTime = DateTime.Now;

                    await _workflowInstanceRepo.UpdateAsync(workflowInstance);

                    // 5. 记录重新提交操作历史
                    var auditRecord = new AuditModel
                    {
                        WorkflowId = request.WorkflowInstanceId.ToString(),
                        StepId = "STEP_" + request.WorkflowInstanceId,
                        StepName = "重新提交",
                        ExecutePointerId = "EP_" + request.WorkflowInstanceId,
                        AuditUserName = request.ApplicantUserName,
                        AuditUserId = 0, // 申请人操作，可以设置为0或实际申请人ID
                        OperationType = "重新提交",
                        Remark = request.ModifyRemark ?? "重新提交申请",
                        Status = false,
                        CreateTime = DateTime.Now,
                        CreatorId = 0
                    };

                    await _auditRepo.CreateAsync(auditRecord);

                    // 提交事务
                    await _workflowInstanceRepo.CommitTranAsync();

                    res.Code = ApiEnum.Success;
                    res.Msg = "重新提交成功";
                    res.Data = true;

                    _logger.LogInformation("重新提交申请成功，流程实例ID: {WorkflowInstanceId}, 申请人: {ApplicantUserName}", 
                        request.WorkflowInstanceId, request.ApplicantUserName);

                    return res;
                }
                catch (Exception)
                {
                    // 回滚事务
                    await _workflowInstanceRepo.RollbackTranAsync();
                    throw;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "重新提交申请失败，WorkflowInstanceId: {WorkflowInstanceId}, ApplicantUserName: {ApplicantUserName}", 
                    request.WorkflowInstanceId, request.ApplicantUserName);
                res.Code = ApiEnum.Fail;
                res.Msg = "重新提交失败：" + ex.Message;
                res.Data = false;
                return res;
            }
        }
    }
} 